/*
 * 文件名:CAudio.hpp
 *
 * 	 功能描述:
 *  创建日期: 2010-11-28
 *  版本Ver0.01
 *  作者: huanying2000
 *  版权:copyright 2010 by the Camellia project 
 *  free software under the terms of the LGPL 2.1
 */

#ifndef CAUDIO_HPP_
#define CAUDIO_HPP_

#include "Globel.hpp"
#include "COutput.h"
#include "CAlsa.hpp"
#include "CSemaphore.hpp"
#include "CSharedMemory.cpp"		//模板类不能分离编译，即声明和实现必须在一起
#include "CAudioTag.h"
#include "CPlayList.h"

void *playThread(void *args);
void *controlThread(void *args);
void *sendDoneSignal(void *args);

class CAudio
{
	friend void *playThread(void *args);
	friend void *controlThread(void *args);

	public:
		enum ENStatus
		{
			STATUS_PLAY,
			STATUS_PAUSE,
			STATUS_UNPAUSE,
			STATUS_STOP,
			STATUS_SEEK,
			STATUS_QUIT,
			VOL_INC,
			VOL_DEC,
			STATUS_NEXT
		};

		CAudio(CPlayList *playList, string cpuAttr = "SSE");
		~CAudio();
		//void reset(long rate, int channels, int format, KAudioOutput *ao);
		bool open(void);
		int play();
		void pause();
		void unpause();
		void stop();
		void prev();
		void next();
		void seek(off_t offset);
		void changeVolumn(const double change);
		//void setVolumn(double step);
		//void control();
		inline ENStatus getPlayStatus(void) const;
		bool getAudioInfo(KAudioInfo *pAudioInfo);
		bool getTagInfo(KAudioTag *pAudioTag);
		off_t getPlayedFrames(void);

	private:
		enum
		{
			DECODE_TEST,
			DECODE_AUDIO,
			DECODE_FILE,
			DECODE_BUFFER,
			DECODE_WAV,
			DECODE_AU,
			DECODE_CDR,
			DECODE_AUDIOFILE
		};

		struct KDecodeParam
		{
			int down_sample;
			long rva; 							/* (which) rva to do: 0: nothing, 1: radio/mix/track 2: album/audiophile */
			long halfspeed;
			long doublespeed;
			long start_frame;  			/* frame offset to begin with */
			long frame_number; 		/* number of frames to decode */
			long outscale;
			int flags;
			long force_rate;
			int talk_icy;
			long resync_limit;
			int smooth;
			double pitch; 					/* <0 or >0, 0.05 for 5% speedup. */
			int ignore_mime; 				/* An mpg123 app flag field in future? */
			char *proxyurl;
			int keep_open; 				/* Whether to keep files open after end reached, for remote control mode, perhaps terminal control, too. */
			int force_utf8; 					/* Regardless of environment, always print out verbatim UTF for metadata. */
			long index_size; 				/* size of frame index */
			char *force_encoding;
			double preload; 				/* buffer preload size (fraction of full buffer) */
			long preframes;
			long gain; 						/* audio output gain, for selected outputs */
			//char *cpu;
			char cpu[32];
			long timeout; 					/* timeout for reading in seconds */
			int verbose;    						/* verbose level */
		};

		int traceFd;
		pid_t childPid;
		off_t frameOff;								//已播放帧数
		off_t seekFrames;							//跳跃的帧数
		string traceName;
		ENStatus status;
		//KAudioOutput kAudioOutput;
		KDecodeParam param;
		CSemaphore sem;
		CPlayList *pPlayList;

		mpg123_handle *mh;
		mpg123_pars *mp;

		inline long pitchRate(long rate);
		int subPlay();
};

extern CAudio *pAudio;
void catchSignal(int signo);					//处理进程发出的各种信号

#endif /* CAUDIO_HPP_ */
